/*
        This file is part of NNF2.

        NNF2 is free software: you can redistribute it and/or modify it
        under the terms of the GNU General Public License as published 
        by the Free Software Foundation, either version 3 of the License,
        or (at your option) any later version.

        NNF2 is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with NNF2.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "RedNeuronal.h"
#include "TestsAManopla.h"
#include "TransferFunction.h"
#define eps 0.5f
#define range 1.5f
using namespace std;

bool parametrosValidos(int argc, char** argv) {
    bool validos = true;
    if (argc <= 1) {
        cout << "No ha ingresado ninguna imagen para analizar" << endl;
        validos = false;
    }
    FILE* fp = fopen(argv[1], "rb");
    if (fp == NULL) {
        cout << "Ha ingresado una imagen inexistente" << endl;
        validos = false;
    }
    return validos;
}

void ayuda()
{
    cout << "El de Red Neuronales se ejecuta de la siguiente manera:"<< endl;
    cout << "./redesneuronales <path imagen a interpretar>" << endl;
}

int main(int argc, char ** argv) {
    
//    if (!parametrosValidos(argc,argv)) {
//        ayuda();
//        return 1;
//    }

    // seed random number generator
    srand(time(NULL));

    // transfer functions
    Sigmoid sigmoid(2.0f); // sigmoid of parameter 2.0
    Heaviside heaviside; // heaviside of default parameter 0
    
    // input layer has 10000 neurons, uses sigmoid transfer function
    InputLayer il(10000, heaviside);

    // hidden layer is connected to input layer, has 4 neurons, uses sigmoid, 
    // has learning rate 'eps' and initial weights in (-range, range)
    Layer hl(&il, 12, sigmoid, eps, range);

    // output layer is connected to hidden layer, has 1 neuron, uses heaviside
    // transfer function
    OutputLayer ol(&hl, 1, heaviside, eps, range);

    // MLP network constructor takes input and output layers and 
    // a NULL-terminated list of hidden layers in the same order 
    // they were connected
    MultiLayerPerceptron mlp(&il, &ol, &hl, NULL);

    // Defino Red a usar
    RedNeuronal* red = new RedNeuronal(&mlp);
    int total = 50000;
    for (int t = 0; t < total ; t++){
        if ( t != (total-1)){
                cout << "Entrenando Red neuronal......." << (int) ((t*100 / total) + 1) << "%\r";
        }else{
                cout<<endl;
        }
    }
    
    red->aprender();
    cout << "Red entrenada" << endl;
    string salida1 = red->interpretar("Aprender/7coma1raros.bmp");
    cout << "La imagen ingresada tiene el número: " << salida1 << endl;
    return 0;
}
